package com.neo4j;

import org.neo4j.driver.v1.AuthTokens;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.GraphDatabase;
import org.neo4j.driver.v1.Session;
import org.neo4j.driver.v1.StatementResult;
import org.neo4j.driver.v1.Transaction;
import org.neo4j.driver.v1.TransactionWork;

public class BaseDriver implements AutoCloseable{
	
	private Driver driver;
	
	/**
	 * 构造函数
	 * @param uri 		链接地址
	 * @param userName	用户名
	 * @param password	用户密码
	 */
	public BaseDriver(String uri,String userName,String password) {
		driver = GraphDatabase.driver(uri, AuthTokens.basic(userName, password));
	}

	@Override
	public void close() throws Exception {
		driver.close();
	}
	
	/**
	 * 判断是否链接上了neo4j数据库
	 * @return
	 */
	public boolean isCOnnect(){
		StatementResult result = driver.session().run("RETURN 1");
		return result.single().get(0).asInt() == 1;
	}
	
	/**
	 * 创建索引
	 * @param nodeLable	节点标签
	 * @param keyName	节点属性
	 */
	public void createIndex(String nodeLabel , String keyName){
		runWriteCQL("CREATE INDEX ON :" + nodeLabel + "(" + keyName + ")");
	}
	
	/**
	 * 写操作，执行cql
	 * @param cql
	 */
	public void runWriteCQL(String cql) {
		try (Session session = driver.session()) {
			session.writeTransaction(new TransactionWork<Void>() {
				@Override
				public Void execute(Transaction tx) {
					tx.run(cql);
					return null;
				}
			});
		}
	}
	
	/**
	 * 非事务性的写操作，执行cql语句
	 * @param cql
	 */
	public void runWriteCQLWithoutTransation(final String cql) {
		try (Session session = driver.session()) {
			session.run(cql);
		}
	}
	
	/**
	 * 读操作，执行cql语句
	 * @param cql
	 * @return
	 */
	public StatementResult runReadCQL(final String cql) {
		try (Session session = driver.session()) {
			return session.readTransaction(new TransactionWork<StatementResult>() {
				@Override
				public StatementResult execute(Transaction tx) {
					return tx.run(cql);
				}
			});
		}
	}

	/**
	 * 非事务性的读操作，执行cql语句
	 * @param cql
	 * @return
	 */
	public StatementResult runReadCQLWithoutTransation(final String cql) {
		try (Session session = driver.session()) {
			return session.run(cql);
		}
	}
}
